/*******************************************************************************
 ** Name: atbios.cpp                                                          **
 ** Description: Definitions for ATBIOS class and helper functions.           **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved License                             **
 **                                                                           **
 ** The contents of this file are subject to the terms of the                 **
 ** Common Development and Distribution License, Version 1.0 only             **
 ** (the "License").  You may not use this file except in compliance          **
 ** with the License.                                                         **
 **                                                                           **
 ** You can find a copy of the license in the license.txt within              **
 ** this distribution or at http://www.munixos.net/licensing.                 **
 ** Software distributed under the License is distributed on an "AS IS"       **
 ** basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.           **
 ** See the License for the specific language governing permissions           **
 ** and limitations under the License.                                        **
 **                                                                           **
 ** When distributing Covered Code, include this CDDL header in each          **
 ** file and include the License file at $HOME/license.txt.                   **
 ** If applicable, add the following below this header, with the indicated    **
 ** fields enclosed by brackets "[]" replaced with your own identifying       **
 ** information: Portions Copyright [yyyy] [name of copyright owner]          **
 **                                                                           **
 **                                                                           **
 ** Copyright (c) 2009-2010  Barry Gian James.                                **
 ** All rights reserved.                                                      **
 **                                                                           **
 ** Ref: $HeadURL$
 ******************************************************************************/
// Portions (C) 2011 OpenHouseware, LLC.
// All Rights Reserved

// $Id$
// Last Modified $DateTime$ by $Author$

#include "atbios.h"
#include "progmem.h"
#include "usart.h"
#include <avr/io.h>
#include <avr/eeprom.h>

uint8   cfgDoInteractive EEMEM;

static IOPort   atbiosMISO(&PORTB,&DDRB,&PINB,PINB6);
static IOPort   atbiosMOSI(&PORTB,&DDRB,&PINB,PINB5);
static IOPort   atbiosSCK(&PORTB,&DDRB,&PINB,PINB7);
// temp using the bus expander !CS since the GPIO expander isn't connected
static IOPort   atbiosSPIMemCS(&PORTB,&DDRB,&PINB,PIN_BUSX_CS);

////////////////////////////[ class ATBIOS

ATBIOS::ATBIOS(uint8 a)
{
    addr    = a;
    spiConfigFlash     = NULL;
    spiTemp = NULL;
    twiRTC  = NULL;
    debug   = NULL;
    bDebug  = true;
    bInteractive = false;
}

bool
ATBIOS::Init()
{
    bInteractive = (bool)eeprom_read_byte((const uint8*)cfgDoInteractive);

    // initialize debug console
    if (bDebug) {
        debug = new USART(57600,(USART_RX|USART_TX));
        debug->Connect();   // connect to the debug console
        // Enable interrupt on serial port data reception
        // TODO - write ISR using interrupt.h structs
        debug->EnableInterrupt(USART_RX);
    }

    // initialize SPI bus to each device
    // Flash Configuration Memory Device
    spiConfigFlash = new SPI();
    spiConfigFlash->DataInPort(&atbiosMOSI);
    spiConfigFlash->DataOutPort(&atbiosMISO);
    spiConfigFlash->ClockPort(&atbiosSCK);
    spiConfigFlash->SelectPort(&atbiosSPIMemCS);
    // attach to devices
    if (spiConfigFlash->Connect() == false) {
        Debug("spiConfigFlash failure");
        return false;
    }

    // SPI Temp Sensor
    spiTemp     = new SPI();
    spiTemp->DataInPort(&atbiosMOSI);
    spiTemp->DataOutPort(&atbiosMISO);
    spiTemp->ClockPort(&atbiosSCK);
    spiTemp->SelectPort(&atbiosSPIMemCS);   // we're using it again
    if (spiTemp->Connect() == false) {
        Debug("spiTemp failure\r\n");
        return false;
    }

    // initialize TWI
    twiRTC = new TWI();
    if (twiRTC->Connect() == false) {
        Debug("twiRTC failure");
        return false;
    }
    return true;
}

void
ATBIOS::SetInteractive(bool b)
{
    if (b)
        eeprom_write_byte(&cfgDoInteractive,1);
    else
        eeprom_write_byte(&cfgDoInteractive,0);

    bInteractive = b;
}

bool
ATBIOS::InitIO()
{
    return false;
}

bool
ATBIOS::InitMem()
{
    return false;
}

bool
ATBIOS::InitKernel()
{
    return false;
}

void
ATBIOS::Debug(const char * msg,bool bProgMem)
{
    if (bDebug)
	{
        if (bProgMem)
            debug->WriteLine(msg);
        else
            debug->WriteRAMStr(msg);
	}
}


void
ATBIOS::SendToVGA(char c)
{

}

TimeStruct
ATBIOS::GetTime()
{
    // TODO - contact RTC

    TimeStruct ts;
    return ts;
}

DateStruct
ATBIOS::GetDate()
{
  // TODO - contact RTC

    DateStruct  ds;
    return ds;
}
